<script setup lang="ts">
/**
 * @author lwlianghehe@gmail.com
 * @date 2025/01/08
 */
import { ref, computed, onMounted, onUnmounted } from "vue";
import { ElButton, ElInput, ElForm, ElFormItem, ElCheckbox } from 'element-plus';
import { SearchReplaceData } from './types';

const props = withDefaults(defineProps<{
  modelValue?: boolean
  title?: string
  width?: string | number
  index?: number
  count?: number
}>(), {
  modelValue: false,
  title: '查找和替换',
  width: '450px',
  index: -1,
  count: 0
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'find-next', data: SearchReplaceData): void
  (e: 'find-previous', data: SearchReplaceData): void
  (e: 'replace', data: SearchReplaceData): void
  (e: 'replace-all', data: SearchReplaceData): void
  (e: 'enter', data: SearchReplaceData): void
  (e: 'change', data: SearchReplaceData): void
  (e: 'close'): void
}>()

const panelRef = ref<HTMLElement>()
const isDragging = ref(false)
const dragOffset = ref({ x: 0, y: 0 })

const panelVisible = computed({
  get: () => props.modelValue,
  set: (val: boolean) => {
    emit('update:modelValue', val)
  }
})

// 计算查询结果显示文本
const searchResultText = computed(() => {
  if (props.count === 0) {
    return '未找到'
  }
  if (props.index >= 0 && props.count > 0) {
    return `${props.index} / ${props.count}`
  }
  return ''
})

// 是否显示查询结果
const showSearchResult = computed(() => {
  return formData.value.findText.trim() !== '' && (props.count >= 0)
})

const formRef = ref()
const formData = ref<SearchReplaceData>({
  findText: '',
  replaceText: '',
  matchCase: false,
  matchWholeWord: false
})

// 处理查找下一个
const handleFindNext = () => {
  if (!formData.value.findText.trim()) return
  emit('find-next', { ...formData.value })
}

// 处理查找上一个
const handleFindPrevious = () => {
  if (!formData.value.findText.trim()) return
  emit('find-previous', { ...formData.value })
}

// 处理替换
const handleReplace = () => {
  if (!formData.value.findText.trim()) return
  emit('replace', { ...formData.value })
}

// 处理全部替换
const handleReplaceAll = () => {
  if (!formData.value.findText.trim()) return
  emit('replace-all', { ...formData.value })
}

// 处理关闭
const handleClose = () => {
  emit('close')
  panelVisible.value = false
}

// 处理输入变化
const handleInputChange = () => {
  emit('change', { ...formData.value })
}

// 处理 Enter 键
const handleEnterKey = () => {
  if (!formData.value.findText.trim()) return
  emit('enter', { ...formData.value })
}

// 重置表单数据
const resetFormData = () => {
  formData.value = {
    findText: '',
    replaceText: '',
    matchCase: false,
    matchWholeWord: false
  }
}

// 拖拽功能
const handleMouseDown = (e: MouseEvent) => {
  isDragging.value = true
  const rect = panelRef.value!.getBoundingClientRect()
  dragOffset.value = {
    x: e.clientX - rect.left,
    y: e.clientY - rect.top
  }
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
  e.preventDefault()
}

const handleMouseMove = (e: MouseEvent) => {
  if (!isDragging.value || !panelRef.value) return
  
  const x = e.clientX - dragOffset.value.x
  const y = e.clientY - dragOffset.value.y
  
  // 限制在视窗内
  const maxX = window.innerWidth - panelRef.value.offsetWidth
  const maxY = window.innerHeight - panelRef.value.offsetHeight
  
  panelRef.value.style.left = Math.max(0, Math.min(x, maxX)) + 'px'
  panelRef.value.style.top = Math.max(0, Math.min(y, maxY)) + 'px'
}

const handleMouseUp = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

// 生命周期
onMounted(() => {
  // 可以在这里设置初始位置
})

onUnmounted(() => {
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
})
</script>

<template>
  <Teleport to="body">
    <div 
      v-if="panelVisible" 
      ref="panelRef"
      class="search-replace-panel"
      :style="{ width: typeof width === 'number' ? width + 'px' : width }">
      
      <!-- 标题栏 -->
      <div class="panel-header" @mousedown="handleMouseDown">
        <span class="panel-title">{{ title }}</span>
        <button class="close-btn" @click="handleClose">×</button>
      </div>
      
      <!-- 内容区 -->
      <div class="panel-body">
        <el-form
          ref="formRef"
          :model="formData"
          label-width="80px"
          @submit.prevent="handleEnterKey">
          
          <el-form-item label="查找内容" required>
            <div class="search-input-wrapper">
              <el-input
                v-model="formData.findText"
                placeholder="请输入要查找的内容"
                clearable
                @keyup.enter="handleEnterKey"
                @input="handleInputChange"
                class="search-input" />
              <span 
                v-if="showSearchResult" 
                class="search-result-text"
                :class="{ 'not-found': props.count === 0 }">
                {{ searchResultText }}
              </span>
            </div>
          </el-form-item>
          
          <el-form-item label="替换为">
            <el-input
              v-model="formData.replaceText"
              placeholder="请输入替换内容"
              clearable
              @input="handleInputChange" />
          </el-form-item>
          
          <el-form-item label="选项">
            <div class="options-container">
              <el-checkbox v-model="formData.matchCase" @input="handleInputChange">
                区分大小写
              </el-checkbox>
              <el-checkbox v-model="formData.matchWholeWord" class="ml-4" @input="handleInputChange">
                全字匹配
              </el-checkbox>
            </div>
          </el-form-item>
        </el-form>
      </div>
      
      <!-- 底部按钮 -->
      <div class="panel-footer">
        <div class="button-group">
          <el-button 
            @click="handleFindPrevious"
            :disabled="!formData.findText.trim()">
            查找上一个
          </el-button>
          <el-button 
            type="primary" 
            @click="handleFindNext"
            :disabled="!formData.findText.trim()">
            查找下一个
          </el-button>
        </div>
        <div class="button-group mt-2">
          <el-button 
            @click="handleReplace"
            :disabled="!formData.findText.trim()">
            替换
          </el-button>
          <el-button 
            @click="handleReplaceAll"
            :disabled="!formData.findText.trim()">
            全部替换
          </el-button>
        </div>
        <div class="button-group mt-2">
          <el-button @click="handleClose">关闭</el-button>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<style scoped>
.search-replace-panel {
  position: fixed;
  top: 100px;
  right: 20px;
  z-index: 2000;
  background: white;
  border: 1px solid #e0e6ed;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  user-select: none;
  pointer-events: auto;
}

.panel-header {
  padding: 12px 20px 8px 20px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  cursor: move;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.panel-title {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  margin: 0;
}

.close-btn {
  background: none;
  border: none;
  font-size: 18px;
  color: #666;
  cursor: pointer;
  padding: 0;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
}

.close-btn:hover {
  background-color: #e9ecef;
  color: #333;
}

.panel-body {
  padding: 15px 20px;
  background-color: #ffffff;
}

.panel-footer {
  padding: 12px 20px 15px 20px;
  background-color: #f8f9fa;
  border-top: 1px solid #e9ecef;
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.el-form-item {
  margin-bottom: 16px;
}

.options-container {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.button-group {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.button-group .el-button {
  flex: 1;
  min-width: 100px;
}

:deep(.el-input__wrapper) {
  border-radius: 4px;
}

:deep(.el-checkbox) {
  margin-right: 0;
}

:deep(.el-checkbox__label) {
  font-size: 14px;
}

.search-input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
}

.search-input {
  flex: 1;
  width: 100%;
}

.search-result-text {
  position: absolute;
  right: 35px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: #409eff;
  background: white;
  padding: 0 4px;
  border-radius: 2px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 1;
}

.search-result-text.not-found {
  color: #f56c6c;
}

/* 确保所有输入框宽度一致 */
:deep(.el-input) {
  width: 100%;
}

:deep(.el-input__wrapper) {
  width: 100%;
}
</style> 